;›;**************************************›;›; RCMDFRM:›; RECIEVE COMMAND FRAME›;›; ENTRY:NONE›; EXIT: NONE›;›; REGISTERS USED:A,X›;›; MEMORY USED:COMMAND FRAME BUFFER›;›;**************************************›;›RCMDFRMPROC›:STATUS=$A0;GET STATUS›;›LDA#$32;50 MS TIMEOUT›JSRSTMO›;›;FILL COMMAND FRAME BUFFER›;›LDA#LOW CMDFRM›STABPNT›LDA#HIGH CMDFRM›STABPNT+1›LDA#$04;GET 4 BYTES FROM ATARI›JSRREAD;GET DATA›;›;WAIT FOR CMD LINE TO GO HIGH›;›RCF002BITDRB;MONITOR CMD LINE›BMIRCF002;STILL LOW KEEP WAITING›;›;CMD LINE HIGH, CHECK CHECK SUM›;›LDA:STATUS;CHECK STATUS›BNERCFERR;BRANCH ON ERROR›;›LDASTAT;SET CHECKSUM OK›AND#$FD›STASTAT›LDA#0›STACMDRT;REZERO RETRYS›LDADRA;READ PORT A›AND#$01›STATEMP›LDADRA›LSRA›AND#$01›EORTEMP›STATEMP›LDADRA›AND#$01›EOR#$01›ASLA›ORATEMP›CLC›ADC#$31;ASCII FOR DRIVE NUMBER›CMPCMDFRM;THIS DEVICE REQUESTED?›BNERCFERR;NO GO BACK AND WAIT››; OK WE GOT A COMMAND, LETS GO AND›; DECODE IT››JSRCMDSEL;DECODE COMMAND››; WE RETURN HERE AFTER PROCESSING›; THE COMMAND›RTS›;›;HANDLE COMMAND FRAME ERROR›;›RCFERRCMP#$02;WAS IT A CHECKSUM?›BEQ:RF002›LDASSTAT›BEQRCFEXT;NO, EXIT›JSRBTOG›JMPRCFEXT›;›:RF002LDACMDRT;HAVE WE BEEN TRYING?›BNE:RF001;YES TRY SOME MORE›JSRBTOG;TOGGLE BAUD RATE AND TRY›LDA#3›STACMDRT;SOME MORE›BNERCFEXT›:RF001DECCMDRT;DECREMENT RETRY›RCFEXTLDA#$01›STA:STATUS›RTS;RETURN TO IDLE CONDITION›EPROC›;›;**************************************››; CMDSEL:›; THIS IS WHERE WE DECODE THE›; COMMAND THAT WE HAVE JUST GOT››; ENTRY:VALID COMMAND FRAME IN›; COMMAND FRAM BUFFER›; EXIT:COMMAND PROCESSED››; MEMORY USED:COMMAND FRAME BUFFER››; REGISTERS USED:A,X›;›; COMMAND SUMMARY›;›; P :WRITE TO DISK NO VERIFY›; W :WRITE TO DISK WITH VERIFY›; R :READ DISK›; S :GET STATUS›; ! :FORMAT DISK›; " :FORMAT DUAL DENSITY›; N :READ DRIVE CONFIG›; O :WRITE DRIVE CONFIG›; ? :RETURN SPEED INDEX›; u :upload data to drive›; r :run program in drive›; s :set load address in drive›; g :seek new track›; c :custom format›; f :sparta dos custom format›; b :track buffer toggle›; a :analyze a track›; w :write a sector with deleted data›; m :upload sector pattern and ›; :and read a track of data›; t :get sector data from m command›; v :upload a sector to write›; n :upload sector pattern and write›; :data from v to track›; j :change drive rpm›; h :set drive on hold time›; d :disable density sense›;›;**************************************››RD=$50;RECEIVE DATA FROM ATARI›RDV=$57;RECEIVE AND VERIFY DATA›WRT=$52;SEND DATA TO ATARI›STATUS=$53;SEND STATUS TO ATARI›RCONFIG=$4E;READ DRIVE CONFIG›WCONFIG=$4F;WRITE DRIVE CONFIG›FORMAT=$21;FORMAT DISK›UPLOAD='u';$75 UPLOAD PROGRAM DATA›RUN='r';$72 RUN PROGRAM›SETADR='s';$73 SET ADDRESS LOAD›GTRACK='g';$67 seek new track›CFRMAT='c';$63 custom format a track›HTME='h';set hang on time (TL)›BAUD='?';SET TO WARP SPEED›TBUFF='b';track buffer toggle›ANAL='a';ANALYZE A TRACK›WDDM='w';WRITE WITH DELETED DTA MARK›;›CMDSELPROC›;›:STATUS=$A0;STATUS FROM GET›;›LDACMDFRM+1;LOAD COMMAND›CMP#RD;DO WE GET DATA FROM ATARI›BEQCSEL00;YES›CMP#RDV;READ WITH VERIFY?›BNECSEL01;NO READ, TRY NEXT COMMAND››;RECIEVE DATA FROM COMPUTER››CSEL00JSRNTS;CALCULATE NEW SECTOR›LDANSEC;LOAD SECTOR NUMBER›JSRCTS;CHECK LENTH OF SECTOR›JSRSBPNT;SET BUFFER POINTER›JSRACK;SEND ACKNOLEDGE›LDALENTH;LENTH OF BUFFER TO RECIEVE›JSRREAD;READ DATA FROM ATARI›LDA:STATUS;GET STATUS›CMP#$02›BNE:CS001›JMPCMDNAK;COMMAND ERROR›:CS001CMP#$01›BNE:CS002;TIMEOUT ERROR?›JMPCMDXIT›:CS002JSRACK›JSRMCK;DO MOTOR CHECK›LDASRATE;SAVE STEP RATE›PHA›LDA#108›STASRATE›JSRSKTK;SEEK TRACK›PLA›STASRATE›LDADTAREG;DO A DUMB READ›LDANSEC›JSRWSEC››BITSTREG;WRITE PROTECT?›BVCC0B;NO PROTECT›JSRERR;PROTECTED, SEND ERROR›JMPC0A;DON'T VERIFY››C0BLDACMDFRM+1;LOAD COMMAND›CMP#$57;READ WITH VERIFY?›BNEC0A;NO VERIFY›LDANSEC›JSRVSEC;VERIFY READ›;›C0ALDA#$FF›STATINB;NO DATA IN TRACK BUFFER›;›CM0002JSRCMPLT;SEND COMPLETE›LDA#$00›STA:STATUS›JMPCMDXIT;EXIT FROM COMMAND PROCESS›;›;CHECK FOR SEND DATA›;›CSEL01CMP#WRT;SEND DATA TO ATARI?›BNECSEL02;NO, TRY NEXT COMMAND›;›; SEND DATA FRAME BACK TO ATARI›;›JSRACK›;›;IF THE PERIPHERAL HAS TO DO SOMETHING›;TO GET THE DATA, IT WOULD DO IT HERE›;›;›;SEE IF IN FORCE SLOW MODE›;›LDATFLAG›BEQ:CS022›;›JSRMCK›;›JSRNTS;CALCULATE NEW TRACK/SECTOR›JSRSKTK;FIND THE TRACK TO READ FIRST›BCSBOUNCE;COMMAND NOT ACKNOLEDGED›;›LDADTAREG›LDANSEC›JSRCTS;CHECK OUT LENTH›JSRSBPNT;SET BUFFER›JSRRSEC;READ SECTOR›LDA:STATUS›BEQ:CS023›JSRCMDERR;SEND ERROR›JMP:CS024;SEND ERROR›:CS023JSRCMPLT›:CS024LDALENTH›JSRSEND›LDA#$00›STA:STATUS;RE INIT MOTOR›JMPCMDXIT›;›:CS022JSRRDTK;READ TRACK›BCSBOUNCE;COMMAND NOT ACKNOLEDGED›LDA:STATUS›PHA;SAVE FOR LATER›LDXNSEC;SET INDEX TO SEC TABLE›DEX›LDATRKCH,X›STASTAT+1;SAVE IN HW STATUS›EOR#$FF;COMPLEMENT STATUS›AND#%00111000;CHECK FOR FDC ERROR›BEQOKSEC;NO ERROR›JSRERR;SEND ERROR›JSRRDSC›PLA;POP STATUS›STA:STATUS›JMPCMDXIT›OKSECJSRCMPLT›JSRRDSC›PLA;POP STATUS›STA:STATUS›JMPCMDXIT;EXIT FROM COMMAND PROCESS›BOUNCEJMPCMDNAK;SEND NAK TO ATARI›;›; IS IT A REQUEST FOR STATUS›;›CSEL02CMP#STATUS;IS IT STATUS›BNECSEL03;NO, TRY NEXT COMMAND››;SEND STATUS››LDA#$E0;SET TIMEOUT›STASTAT+2›LDA#$24;WHO KNOWS WHY?›STASTAT+3›JSRACK›JSRDELAY;WAIT BEFORE SENDING COMPLT›JSRCMPLT;SEND COMPLETE›JSRSDSTAT;SEND STATUS›LDA#$01›STA:STATUS;DO NOT REINIT TIMER›JMPCMDXIT;EXIT FROM COMMAND PROCESS›››;READ CONFIGURATION FROM DRIVE››CSEL03CMP#RCONFIG;READ CONFIG?›BNECSEL04;NO, TRY NEXT COMMAND›;›JSRDELAY›JSRACK;ACKNOWLEDGE CMD›JSRDELAY;WAIT TO SEND CMPLT›JSRCMPLT;SEND OPERATION COMPLETE›LDALENTH›PHA;SAVE LENGTH ON STACK›LDA#12;12 BYTES TO SEND›STALENTH›LDA#LOW CONFIG›STABPNT;POINTER TO DATA TO SEND›LDA#HIGH CONFIG›STABPNT+1›LDALENTH›JSRSEND;SEND CONFIG TO ATARI›PLA›STALENTH;RESTORE LENTH›LDA#1›STA:STATUS;DO NOT REINT TIMER›JMPCMDXIT›››;WRITE CONFIGURATION TO DRIVE››CSEL04CMP#WCONFIG;WRITE CONFIG?›BNECSEL05;NO, TRY NEXT COMMAND››JSRACK;ACKNOWLEDGE CMD›LDA#$FF›JSRSTMO;SET TIME OUT›LDA#$0C;SET TO READ 12 BYTES›LDX#LOW CONFIG;SET POINTER BPNT›STXBPNT›LDX#HIGH CONFIG;STORE DATA›STXBPNT+1›;›JSRREAD;READ DATA FROM SERIAL BUS›LDA:STATUS›CMP#$02›BNEC4A10›JMPCMDERR›C4A10CMP#$01›BNEC4A11›JMPCMDNAK›C4A11JSRDELAY›JSRACK›;›LDACONFIG+5;CHECK DENSITY CONTROL›AND#$04›BEQC4A12›LDACONFIG+3›CMP#18;CHECK FOR DUAL DENS›BEQC4A14›LDASTAT›AND#%01011111›ORA#%10000000›STASTAT›JMPC4A13›;›C4A14LDASTAT;DOBLE DENSITY›AND#%01011111›ORA#%00100000›STASTAT›JMPC4A13›;›C4A12LDASTAT;SINGLE DENSITY›AND#%01011111›STASTAT›C4A13JSRDELAY›JSRCMPLT;SEND OPERATION COMPLETE›LDA#$01›STA:STATUS;DO NOT REINIT TIMER›;›JMPCMDXIT›;›CSEL05CMP#FORMAT;FORMAT?›BEQCSEL5›JMPCSEL06;NO NEXT COMMAND!!›;›CSEL5JSRACK›JSRMCK;DO MOTOR THING›LDASRATE;SAVE STEP RATE›PHA›LDA#200;REAL SLOW MAN!›STASRATE›LDA#0›STANTRK;GOTO TRACK 0›JSRSKTK›;›;CHECK THE TYPE OF FORMAT›;›LDA#$04›ANDCONFIG+5›BEQ:CS501;SINGLE DENSITY›LDACONFIG+3›CMP#26›BEQ:CS501›;›;DOUBLE DENS›;›LDASTAT;SET STATUS TO DD›AND#%01011111›ORA#%00100000›STASTAT›JSRDFLTS;SET DEFAULT SKEW›JSRDDFMT›PLA›STASRATE;RESTORE STEP RATE›;›;CHECK FDC›;›LDA#39;ON TRACK 39›JSRFDCCK›LDA:STATUS›BNE:CS506›;›LDA#$BF›JSRVDSK›LDA:STATUS›BEQ:CS502›:CS506JSRERR›JMP:CS503›;›:CS502JSRCMPLT›:CS503LDA#$20›STABPNT+1›LDA#$00›STABPNT›JSRSEND›LDA#$00›STA:STATUS›JMPCMDXIT›;›:CS501LDASTAT›AND#%01011111›STASTAT›LDA#18›STACONFIG+3›LDA#0›STACONFIG+5›STACONFIG+6›LDA#128›STACONFIG+7›JSRDFLTS›JSRSFRMAT›PLA›STASRATE;RESTORE STEP RATE›;›LDA#39›JSRFDCCK;CHECK FDC WITH TRACK 39›LDA:STATUS›BNE:CS507›LDA#0›JSRVDSK›LDA:STATUS›BEQ:CS504›:CS507JSRERR›JMP:CS505›;›:CS504JSRCMPLT›:CS505LDA#0›STABPNT›LDA#$20›STABPNT+1›LDA#$80›JSRSEND›;›LDA#0›STA:STATUS;REINIT TIMER›JMPCMDXIT›;›;**************************************›;›;THESE ARE SPECIAL COMMANDS FOR USERS›;TO LOAD THEIR OWN PROGRAMS UP TO THE›;DUPLICATOR BOARD. THIS ALSO PUTS LESS›;BURDEN ON US AS HACKERS WILL LOVE TO›;MESS WITH THE DRIVE›;›;**************************************›;›CSEL06CMP#SETADR;SET START ADRESS?›BNECSEL07;NO, NEXT COMMAND›;›;THE START ADDRESS IS CONTAINED IN›;AUX1 AND AUX2 OF THE COMMAND FRAME›;›JSRDELAY;WAIT JUST A BIT›JSRACK›LDACMDFRM+2;LOAD AUX1›STASTRADR›LDACMDFRM+3;LOAD AUX2›STASTRADR+1›JSRDELAY›JSRCMPLT›LDA#1›STA:STATUS›JMPCMDXIT;OPERATION COMPLETE›;›CSEL07CMP#UPLOAD;UPLOAD COMMAND›BNECSEL08;NOPE, TRY NEXT ONE›;›;THIS COMMAND WILL START LOADING DATA›;IN 256 BYTE CHUNKS STARTING AT THE›;ADDRESS SET IN THE SET START ADDRESS›;COMMAND. AFTER DATA HAS BEEN LOADED›;THE START ADDRESS WILL BE INCREMENTED›;BY ONE PAGE. IF IT IS POINTING TO›;AN AREA OF MEMORY THAT DOES NOT EXIST›;ON TE DUPLICATOR, THEN AN ERROR IS›;RETURNED›;›JSRDELAY›JSRACK›JSRULD;UPLOAD THE DATA FROM ATARI›;›;ULD RETURNS STATUS IN $A0›;›JSRDELAY›JSRACK›JSRDELAY›LDA:STATUS;CHECK STATUS FROM ULD›CMP#2;MEMORY BOUND ERROR?›BNECSEL72›JMPCMDERR;YES,SEND BACK ERROR›CSEL72CMP#1;CHECKSUM ERROR?›BNECSEL71›JMPCMDNAK;SEND NACK›CSEL71JSRCMPLT›LDA#1›STA:STATUS›JMPCMDXIT›;›CSEL08CMP#RUN;RUN PROGRAM COMMAND?›BNECSEL09;NO, NEXT COMMAND›;›;DO AN INDIRECT JUMP TO ADDRESS PASSED›;IN AUX1 AND AUX2. USER ROUTINE MUST›;PERFORM AN RTS TO RETURN TO CRET AND›;MUST RETURN A STATUS IN MEM LOCATION›;$A0 WHERE $00=OK, $02=ERROR›;›JSRDELAY›JSRACK›LDA#HIGH [CRET-1];PUT RETURN ADDRESS›PHA;ONTO THE STACK›LDA#LOW [CRET-1]›PHA›LDACMDFRM+3›PHA;PUSH ADDRESS ON STACK TO›LDACMDFRM+2;JUMP TO›PHA›RTS›CRETJSRDELAY;DO DELAY›LDA:STATUS;GET STATUS›CMP#2›BNECRET1›JMPCMDERR›CRET1JSRCMPLT;STATUS OK›LDA#$01›STA:STATUS;DO NOT REINT TIMER›JMPCMDXIT›;›CSEL09CMP#GTRACK;SEEK TRACK?›BNECSEL10;NO NEXT COMMAND›;›;NEW TRACK NUMBER IS IN AUX1›;›JSRDELAY;WAIT A BIT›JSRACK;SEND ACK›LDA#41;CHECK FOR ILLEAGE TRACK›CMPCMDFRM+2;COMPARE WITH AUX1›BCSCSEL99›JMPCMDERR›CSEL99JSRMCK;TURN ON MOTOR›LDACMDFRM+2›STANTRK›JSRSKTK;SEEK TRACK›JSRCMPLT;SEND COMMPLETE›LDA#$01›STA:STATUS;DO NOT RE-INIT›JMPCMDXIT›;›;›CSEL10CMP#CFRMAT;CUSTOM FORMAT?›BNECSEL11›;›;DO A USER SET CUSTOM FORMAT›;›JSRDELAY;WAIT A BIT›LDA#LOW CFMTBF;SET UP POINTER TO›STABPNT;CUSTOM FORMAT BUFFER›LDA#HIGH CFMTBF›STABPNT+1›JSRACK›LDA#1;READ IN ONE BYTE›JSRREAD›;›LDA:STATUS;CHECK STATUS›BEQ:CS101;BRANCH IF OK›CMP#2;CHECK SUM?›BNE:CS102›LDA#$01›STA:STATUS;DO NOT REINT MOTR›JMPCMDNAK›;›:CS102LDA#$01›STA:STATUS›JMPCMDXIT;TIMEOUT››:CS101JSRDELAY›JSRACK;SEND ACKNOWLEDGE›JSRMCK;DO MOTOR THING›LDA#$20;PUT INTO SD MODE›ORADRA›STADRA›LDA#$80›STALENTH›STACONFIG+7›LDA#$0›STACONFIG+6›LDA#$FB›ANDCONFIG+5›STACONFIG+5›LDA#18›STACONFIG+3›LDASTAT›AND#$5F›STASTAT›LDACFMTBF;LOAD TRACK TIME›JSRCFMT;DO FORMAT›LDA:STATUS;CHECK STATUS›BEQ:CS10›LDATRACK;GET TRACK NUMBER›JSRFDCCK;CHECK THIS TRACK›LDA#0›STA:STATUS›JMPCMDERR;ERROR IN FORMAT›:CS10JSRCMPLT;SEND COMPLETE›LDA#0›STA:STATUS;DO MOTOR THING›JMPCMDXIT›;›;›CSEL11CMP#HTME;SET MOTOR HANG ON›BNECSEL12;NOPE TRY NEXT ONE›;›;SET LOCATION TL WITH CONTENTS OF AUX1›;›JSRDELAY;WAIT A BIT›JSRACK;SEND ACK›LDACMDFRM+2›STATL›JSRDELAY›JSRCMPLT;SEND COMMPLETE›LDA#$01›STA:STATUS;DO NOT RE-INIT›JMPCMDXIT›;›;›CSEL12CMP#BAUD;CHANGE BUAD RATE?›BNECSEL13;NO NEXT COMMAND›;›;SET DUPLICATOR TO ULTRA SPEED MODE›;›JSRDELAY;WAIT A BIT›JSRACK;SEND ACC›JSRDELAY›JSRCMPLT;SEND COMPLETE›LDA#$0A;SEND ONE BYTE OF DATA BACK›JSRPUT;AN $0A? OH WELL WHO KNOWS›LDA#$0A›JSRPUT›LDAFPVEC›STAPUT+1›LDAFPVEC+1›STAPUT+2›LDAFGVEC›STAGET+1›LDAFGVEC+1›STAGET+2;SET UP FAST GET AND PUT›LDA#$01›STA:STATUS›JMPCMDXIT›;›CSEL13CMP#TBUFF;TOGGLE TRACK BUFFER?›BNECSEL14;NO NEXT COMMAND›;›JSRDELAY;WAIT A BIT›JSRACK;SEND ACC›JSRDELAY›JSRCMPLT;SEND COMPLETE›LDACMDFRM+2;LOAD AUX1›STATFLAG›JMPCMDXIT›;›CSEL14CMP#ANAL;ANALYZE TRACK?›BNECSEL15;NO›;›JSRDELAY›JSRACK›JSRMCK;CHECK MOTOR›LDA#0›STABPNT›LDA#$20›STABPNT+1›LDY#0›TYA›;›;ZERO TRACK INFO BUFFER›;›:CS140STA(BPNT),Y›INY›BNE:CS140›INCBPNT+1›LDXBPNT+1›CPX#$24›BNE:CS140›;›JSRANL;ANALYZE TRACK›LDA:STATUS›PHA›LDA:STATUS+1›PHA›LDA#0›STABPNT›LDA#$20›STABPNT+1›PLA›LDY#$FE›STA(BPNT),Y;PUT NUMBER OF SECTORS›INY›PLA›STA(BPNT),Y;STATUS OF OPERATION›JSRCMPLT;OPERATION OK›LDA#0;LENTH OF 256 BYTES›JSRSEND›LDA#$00›STA:STATUS›JMPCMDXIT›;›CSEL15CMP#WDDM;WRITE D.D.M.›BNECSEL16›;›JSRMCK›JSRNTS;CALCULATE NEW TRACK/SECTOR›JSRCTS›JSRSBPNT›JSRACK›LDALENTH›JSRREAD›LDA:STATUS›CMP#$02;BAD READ›BNE:CS150;STATUS OK›LDA#$00›STA:STATUS;REINIT MOTOR TIME›JMPCMDNAK;SEND NAK›;›:CS150CMP#$01;TIME OUT?›BNE:CS151;NO›LDA#0›STA:STATUS;REINTI MOTOR TIME›JMPCMDXIT;YES›;›:CS151JSRACK›JSRSKTK;SEEK TRACK›LDADTAREG;DO DUMB READ›BITSTREG;CHECK FOR WRITE PROTECT›BVC:CS152;OK›JMPCMDERR;SEND ERROR›;›:CS152LDANSEC›JSRSWS›LDA#$FF›STATINB;CLEAR TRACK IN BUFFER›JSRCMPLT›LDA#0›STA:STATUS;REINIT MOTOR›JMPCMDXIT›;›;›CSEL16CMP#'f';IS IT A CUSTOM SECT SK›BEQ:CS16›JMPCSEL17;NO, NEXT COMMAND›;›:CS16LDA#0›STABPNT;SET UP BUFFER POINTER TO ›LDA#$20;RECIEVE CONFIG DATA FROM›STABPNT+1;COMPUTER›JSRDELAY›JSRACK;SAY WE ARE READY›;›LDA#128;GET 128 BYTES›JSRREAD›LDA:STATUS›CMP#$01;TIME OUT›BNE:CS161›JMPCMDXIT;JUST ABORT›:CS161CMP#2;CHECKSUM ERROR?›BNE:CS162›JMPCMDNAK;SEND NAK›;›:CS162JSRACK›LDX#0›LDY#0›:CS163LDA(BPNT),Y›STACONFIG,X›INY›INX›CPX#12;MOVED ALL CONFIG BYTES?›BNE:CS163›;›LDX#0›:CS164LDA(BPNT),Y›BEQ:CS165;EXIT WHEN SECTOR IS ZERO›STASKTAB,X›INX›INY›JMP:CS164›;›:CS165JSRMCK;TURN ON MOTOR›LDASRATE;SAVE STEP RATE›PHA›LDA#200;REAL SLOW MAN›STASRATE›LDA#0›STANTRK›JSRSKTK›LDACONFIG+5;CHECK FOR DD›AND#$04›BEQ:CS167;SINGLE OR DUAL DENSITY›LDACONFIG+3›CMP#26;EIGHTEEN SECTORS›BEQ:CS167›;›;DOUBLE DENSITY›;›LDASTAT›AND#%01011111›ORA#%00100000›STASTAT›JSRDDFMT;FORMAT DISK›PLA;RESTORE STEP RATE›STASRATE›;›;CHECK FDC›;›LDA#39›JSRFDCCK›LDA:STATUS›BNE:CS169›;›LDA#$BF;VERIFY DATA›JSRVDSK›LDA:STATUS›BEQ:CS16C;SEND COMPLETE›:CS169JSRERR›LDA#$00›STA:STATUS›JMPCMDXIT›;›;›;DENSITY AND A HALF›;›:CS167LDASTAT›AND#%01011111›ORA#%10000000›STASTAT›JSRDAHF›PLA;RESTORE STEP RATE›STASRATE›;›;CHECK FDC›;›LDA#128›STALENTH›LDA#39›JSRFDCCK›LDA:STATUS›BNE:C1691›LDA#$BF;VERIFY DATA›JSRVDSK›LDA:STATUS›BEQ:CS16C›:C1691JSRERR›LDA#$0›STA:STATUS›JMPCMDXIT›;›;SINGLE DENSITY FORMAT›;›:CS168LDASTAT›AND#%01011111›STASTAT›JSRSFRMAT;FORMAT DISK›PLA;RESTORE STEP RATE›STASRATE›;›LDA#39›JSRFDCCK›LDA:STATUS›BNE:C1692›LDA#$00›JSRVDSK›LDA:STATUS;CHECK STATUS›BEQ:CS16C›:C1692JSRERR;SEND ERROR›LDA#$00›STA:STATUS›JMPCMDXIT›;›:CS16CJSRCMPLT›JMPCMDXIT›;›CSEL17CMP#'m';upload sector pattern›;read track into buffer›BNECSEL18›;›;**************************************›;›; THIS COMMAND WILL TAKE AUX1, AND USE›; IT AS THE TRACK NUMBER, AND THE FIRST›; PACKET OF NON-ZERO NUMBER IN THE 128›; BYTE BUFFER SENT TO BE THE SECTOR›; PATTERN. IT WILL THEN READ THE ›; SECTORS IN THAT PATTERN INTO THE›; BUFFER AT $2000›;›;**************************************›;›JSRGBH;GET A 128 BYTE BUFFER›LDA:STATUS›BEQ:CS171›CMP#2;CHECKSUM ERROR?›BNE:CS172›LDA#0›STA:STATUS›JMPCMDNAK›:CS172LDA#0;TIMEOUT ERROR›STA:STATUS›JMPCMDXIT›;›:CS171JSRACK›;›;MOVE SECTOR SKEW TABLE›;›JSRMCK;CHECK MOTOR›LDX#0›LDY#0›:CS173LDA(BPNT),Y›STASKTAB,X›INX›INY›CPX#26›BNE:CS173›;›JSRSRT;GO DO SPECIAL RD TRCK›LDA:STATUS›BEQ:CS174›LDA#0›STA:STATUS›JMPCMDERR;SEND ERROR›;›:CS174JSRCMPLT;SEND COMPLETE›LDA#$00›STA:STATUS›STABCNT;INIT BUFFER COUNT FRO›;COMMAND "t"›JMPCMDXIT›;›CSEL18CMP#'t';GET SECTOR FROM BUFFER›BNECSEL19;NEXT COMMAND›;›;**************************************›;›; THIS COMMAND WORKS IN CONJUCTION WITH›; "r". IT WILL READ BACK THE SECTOR›; DATA ONE AT A TIME WITH THE FDC STAT›; RETURNED WITH EACH ONE›;›; ON EACH READ, THE NEXT BUFFER IS ›; RETURNED, IT IS ASSUMED THAT THE›; USER KNOWS BETTER›;›;**************************************›;›:SERR=$3F00;SPECIAL PLACE TO PUT›;TRACK ERRORS IF ANY›;›JSRDELAY›JSRACK›LDA#0›STABPNT;SET UP POINTER BASE›LDA#$20›STABPNT+1›;›;ADD OFFSET ACORDING TO BCNT›;›LDABCNT›LDX#$80›JSRMULT;DO MULTIPLY›CLC›ADCBPNT›STABPNT›TXA›ADCBPNT+1›STABPNT+1›;›JSRCMPLT›LDA#128›JSRSEND›LDXBCNT›LDA:SERR,X›STASTAT+1;PUT FDC STATUS IN STAT LOC›LDA#$01;DO NOT REINIT MOTOR TIMEOUT›STA:STATUS›INCBCNT;NEXT BLOCK OF DATA›JMPCMDXIT›;›CSEL19CMP#'v';upload sctrs to write›BNECSEL20;NO NEXT COMMAND›;›;**************************************›;›; THIS COMMAND LOADS SECTORS TO WRITE›; TO THE DISK. AUX1 CONTAINS THE›; BUFFER NUMBER (NOT THE SECTOR #) AND›; AUX2 CONTAINS THE TYPE OF ERROR IF›; ANY THAT SECTOR IS TO CONTAIN›;›;**************************************›;›AUX1=CMDFRM+2›AUX2=AUX1+1›;›LDAAUX1;GET BUFFER POSITION NUMBER›LDX#$80;SIZE OF BUFFER›JSRMULT›CLC;CALCULATE BUFFER ADDRESS›ADC#$00›STABPNT›TXA›ADC#$20›STABPNT+1›;›JSRACK;SEND ACKNOLEDGE›LDA#128›JSRREAD;READ BUFFER›LDA:STATUS;CHECK STATUS›BEQ:CS191;BRANCH IF OK›CMP#2;CHECK SUM?›BNE:CS192›LDA#$01›STA:STATUS;DO NOT REINT MOTR›JMPCMDNAK›;›:CS192LDA#$01›STA:STATUS›JMPCMDXIT;TIMEOUT›;›:CS191JSRACK›LDAAUX2›LDXAUX1›STA:SERR,X›JSRDELAY›JSRCMPLT›LDA#$01›STA:STATUS›JMPCMDXIT›;›CSEL20CMP#'n';upload sector pattern›;and write buffers to disk›BNECSEL21;NOPE NEXT COMMAND›;›JSRGBH;GET SECTOR SKEW DATA›LDA:STATUS›BEQ:CS201;BRANCH IF DATA GOOD›CMP#$02;CHECKSUM ERROR?›BNE:CS202›LDA#$0›STA:STATUS;REINIT MOTOR›JMPCMDNAK›:CS202LDA#0›STA:STATUS›JMPCMDXIT›;›:CS201JSRACK›JSRMCK;DO MOTOR CHECK›LDX#0›LDY#0;MOVE SECTOR SKEW DATA›:CS203LDA(BPNT),Y›STASKTAB,X›INX›INY›CPX#26›BNE:CS203›;›JSRSPWT›LDA:STATUS›BEQ:CS204›LDA#0›STA:STATUS›JMPCMDERR;SEND ERROR›:CS204JSRCMPLT›JMPCMDXIT›;›CSEL21CMP#'j';rpm change?›BNECSEL22›;›JSRDELAY›JSRACK›LDACMDFRM+2;LOAD AUX1›;›;AUX1=0 IS NORMAL SPEED›;AUX1=1 IS SLOW SPEED›;›BNE:CS211›;›;NORMAL SPEED›;›LDADRA›ORA#$04;SPEED CHANGE BIT›STADRA›JMP:CS212›;›:CS211LDADRA;SLOW SPEED›AND#$FB›STADRA›;›:CS212JSRDELAY›JSRCMPLT›LDA#$01›STA:STATUS;DO NOT REINT MOTOR›;›CSEL22CMP#$22;DUAL DENS FORMAT›BNECSEL23›;›JSRACK›LDASTAT›AND#%01011111›ORA#%10000000›STASTAT›LDA#26›STACONFIG+3›LDA#0›STACONFIG+6›LDA#4›STACONFIG+5›LDA#128›STACONFIG+7›JSRMCK›LDASRATE›PHA;SAVE STEP RATE›LDA#200;REAL SLOW MAN›STASRATE›JSRDAHF;DO DENS AND HALF FORMAT›PLA;RESTORE STEP RATE›STASRATE›;›LDA#128›STALENTH›LDA#39;CHECK FDC ON TRACK 39›JSRFDCCK›LDA:STATUS›BNE:CS221›LDA#$BF;VERIFY DATA›JSRVDSK›LDA:STATUS›BEQ:CS220›:CS221JSRERR;SEND ERROR›JMP:CS222›;›:CS220JSRCMPLT›:CS222LDA#$20›STABPNT+1›LDA#0›STABPNT›LDA#128›JSRSEND›;›LDA#0›STA:STATUS›JMPCMDXIT›;›CSEL23CMP#'d›BNECSEL24›;›; THIS COMMAND SETS A FLAG ACORDING›; TO AUX 1, IF AUX1=0 THE FLAG IS DO›; DENSITY TEST, IF AUX<>1 THEN DON'T›;›JSRDELAY›JSRACK›LDACMDFRM+2›STADCKFLG›JSRDELAY›JSRCMPLT›LDA#$01›STA:STATUS›JMPCMDXIT›;›CSEL24JMP(CSELXX);USR DECODE ROUTINE›;›;COMMAND ERROR›;›CMDERRJSRDELAY›JSRERR›JMPCMDXIT›;›;BAD COMMAND›;›;BAD COMMAND NAK›;›CMDNAKJSRDELAY;WAIT BEFORE NAK SENT›JSRNAK;SEND NOT ACKNOLEDGE›;›CMDXITRTS›;›;**************************************›;›; MCK: MOTOR CHECK›;›; ENTRY:NONE›; EXIT:NONE›;›;**************************************›;›MCKPROC›;›LDAMFLAG;CHECK MOTOR ON FLAG›BNE:MC01›JSRMOON;TURN ON MOTOT›LDX#40;200MSEC WAIT›:LOOPJSRSWAIT›DEX›BNE:LOOP›:MC01RTS›;›EPROC›;›;**************************************›;›; GBH :GET A BUFFER OF DATA AND PUT›; :IT AT $2000›;›; ENTRY:NONE›; EXIT:STATUS SAME AS READ›;›;**************************************›;›GBHPROC›;›:STATUS=$A0›;›;SET UP BUFFER POINTER›;›LDA#0›STABPNT›LDA#$2E›STABPNT+1›JSRDELAY›JSRACK;SEND ACK TO COMPUTER›LDA#128›JSRREAD›RTS›EPROC›;›;›LINKD2:DD15M3.ASM›CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC